<?php
/**
 * IMint
 * 
 * 模板处理类，命名为mint
 *
 * @version $Id: IMint.php 316 2008-05-04 10:50:39Z iwind $
 * @package util.mint
 */
class IMint extends IObject {
	/**
	 * 模板选项
	 *
	 * @var array
	 */
	private static $options = array();
	
	/**
	 * 设置选项
	 *
	 * @param array $options 选项
	 */
	public static function setOptions(array $options) {
		self::$options = $options;
	}
	
	/**
	 * 设置单个选项的值
	 *
	 * @param string $name 选项名
	 * @param mixed $value 选项之
	 */
	public static function setOption($name, $value) {
		self::$options[$name] = $value;
	}

	/**
	 * 取得选项的值
	 *
	 * @param string $name 选项名
	 * @return mixed
	 */
	public static function getOption($name) {
		if (isset(self::$options[$name])) {
			return self::$options[$name];
		}
		return null;
	}
	
	/**
	 * 根据模板名取得文件对象
	 * 
	 * 将会在配置的<i>template-dir</i>中找扩展名为<i>template-extension</i>的文件
	 * 
	 * 从0.0.3起，加入$format参数
	 * 
	 * 从0.2.1起，可以对模板文件进行模糊查找（不区分大小写、下划线忽略），比如如果找不到helloworld的对应的模板，就可以找到hello_world。
	 * 
	 * @param string $template 模板名
	 * @param string $format 格式
	 * @return IFile
	 */
	public static function getFile($template, $format = IMintConfig::HTML_FORMAT) {
		self::validateOptions();
		if (!array_key_exists("template-extension", self::$options)) {
			$extension = IMintConfig::$formatConfig[$format]["extension"]; 
		}
		else {
			$extension = self::$options["template-extension"];
		}
		$path = self::$options["template-dir"] . "/" . $template . $extension;
		$file = new IFile($path);
		if (!$file->exists()) {
			//尝试模糊查找
			$dir = new IFile(self::$options["template-dir"] . "/");
			$fileList = $dir->getList("*" . $extension, true);
			foreach ($fileList as $tplFile) {
				if (strtolower(str_replace("_", "", $file->getPath())) == strtolower(str_replace("_", "", $tplFile->getAbsolutePath()))) {
					return $tplFile;
				}
			}
			throw new IMintException("template file '" . $path . "' does not exist");
		}
		return $file;
	}	
	
	/**
	 * 验证mint配置选项
	 *
	 * @return boolean
	 */
	public static function validateOptions() {
		$compileDir = IMint::getOption("compile-dir");
		$templateDir = IMint::getOption("template-dir");
		if ($compileDir == null || $templateDir == null) {
			throw new IMintException("mint option either 'compile-dir' or 'template-dir' is not declared");
		}
		
		//format
		if (!array_key_exists("text-format", self::$options)) {
			self::$options["text-format"] = IMintConfig::HTML_FORMAT;
		}
		if (!array_key_exists(self::$options["text-format"], IMintConfig::$formatConfig)) {
			throw new IMintException("undefined text format '" . self::$options["text-format"] . "'");
		}
		
		if (!isset(self::$options["template-extension"])) {
			self::$options["template-extension"] = ".html";
		}
		if (!isset(self::$options["mode"])) { //debug user
			self::$options["mode"] = "user";
		}
		if (is_dir($compileDir) && is_dir($templateDir)) {
			return true;
		}
		$compileFile = IApplication::getRelativeFile($compileDir);
		$templateFile = IApplication::getRelativeFile($templateDir);
		if (!$templateFile->exists() || !$templateFile->isDirectory()) {
			throw new IMintException("can't find template dir <strong>'{$templateDir}'</strong> for mint");
		}
		if (!$compileFile->exists() || !$compileFile->isDirectory()) {
			throw new IMintException("can't find compile dir <strong>'{$compileDir}'</strong> for mint");
		}		
		IMint::setOption("compile-dir", $compileFile->getAbsolutePath());
		IMint::setOption("template-dir", $templateFile->getAbsolutePath());
	
		return true;
	}
	
	/**
	 * 添加组件处理器
	 * 
	 * 用户可以使用此方法加入自己的组件
	 *
	 * @param string $name 组件名
	 * @param string $className 组件处理类
	 * @param string $prefix 前缀，@since 0.2
	 * @since 0.0.2
	 */
	public static function addComponentProcessor($name, $className, $prefix = null) {
		IMintConfig::$components[$name] = array(
			"class" => $className,
			"prefix" => $prefix
		);
	}
	
	/**
	 * 添加“修饰”(modifier)处理器
	 * 
	 * 用户可以使用此方法加入自己的modifier
	 *
	 * @param string $name modifier名
	 * @param string $className modifier处理类
	 * @since 0.0.2
	 */
	public static function addModifierProcessor($name, $className) {
		IMintConfig::$modifiers[$name] = $className;
	}
	
	/**
	 * 对不需要转换的字符串加入反斜杠
	 * 
	 * 如{@aa} --> {\@aa}, {$aa} --> {\$aa}
	 *
	 * @param string $string 字符串
	 * @return string
	 * @since 0.0.3
	 */
	public static function addslashes($string) {
		foreach (IMintConfig::$variableMarkArray as $mark) {
			$mark = preg_quote($mark, "/");
			$string = preg_replace("/(\{|%7B)({$mark})/i", "\\1\\\\" . "\\2", $string);
		}
		return $string;
	}
}

?>